package services

import (
	"context"
	"fmt"
	"github.com/cloudwego/hertz/pkg/common/hlog"
	"mall_frontend_api/biz/consts"
	"mall_frontend_api/biz/dal/email"
	"mall_frontend_api/biz/dal/kv"
	"mall_frontend_api/biz/handler/base"
	"mall_frontend_api/biz/model/common"
	"mall_frontend_api/biz/util"
	"strings"
	"time"
)

type EmailService struct {
	common *base.Response
	ctx    context.Context
}

func NewEmailService(ctx context.Context, c *base.Response) *EmailService {
	return &EmailService{
		common: c,
		ctx:    ctx,
	}
}

func (es *EmailService) SendMail(userEmail string, t common.SendEmailType) error {
	var (
		subject string
		body    string
		err     error
	)
	switch t {
	case common.SendEmailType_Register:
		subject, body, err = es.buildRegisterEmail(userEmail)
	case common.SendEmailType_ResetPassword:
		subject, body, err = es.buildResetPasswordEmail(userEmail)
	}
	if err != nil {
		hlog.CtxErrorf(es.ctx, "build email subject failed: %v", err)
		return err
	}
	if subject == "" || body == "" {
		hlog.CtxWarnf(es.ctx, "subject or body is empty")
		return nil
	}

	if err = email.NewGOMail().SendEmail(es.ctx, userEmail, subject, body); err != nil {
		hlog.CtxErrorf(es.ctx, "send email error: %v", err)
		return err
	}
	return nil
}

func (es *EmailService) buildRegisterEmail(userEmail string) (string, string, error) {
	code := strings.ToUpper(util.GetRandomCode(6))
	if err := kv.GetRedisClient().Set(fmt.Sprintf(consts.RedisRegisterUserToken, userEmail), code, 5*time.Minute).Err(); err != nil {
		hlog.CtxErrorf(es.ctx, "build register email error: %v", err)
		return "", "", err
	}
	content := `
Hello,
	Thank you for creating an account with Mall. The code is <span style='background-color:#e5e5e5;font-weight:bold;'>%s</span>.The code is only valid for 5 minute.

`
	return "register email", fmt.Sprintf(content, code), nil
}

func (es *EmailService) buildResetPasswordEmail(userEmail string) (string, string, error) {
	code := strings.ToUpper(util.GetRandomCode(8))
	if err := kv.GetRedisClient().Set(fmt.Sprintf(consts.RedisResetPassword, userEmail), code, 5*time.Minute).Err(); err != nil {
		hlog.CtxErrorf(es.ctx, "build reset password error: %v", err)
		return "", "", err
	}
	content := `
Hello,
	 The code is <span style='background-color:#e5e5e5;font-weight:bold;'>%s</span>.The code is only valid for 5 minute.

`
	return "reset password email", fmt.Sprintf(content, code), nil
}
